Technical Q&A QA1188
GetProcAdress and OpenGL Entry Points


Q: OpenGL ÉGÉìÉgÉäÉ|ÉCÉìÉgÇ÷ÇÃä÷êîÉ|ÉCÉìÉ^ÇéÊìæÇ∑ÇÈÇ…ÇÕÅAǫǧǵÇΩÇÁÇÊÇ¢ÇÃÇ≈ǵÇÂǧǩÅH

A: OpenGL ÉGÉìÉgÉäÉ|ÉCÉìÉgÇ÷ÇÃä÷êîÉ|ÉCÉìÉ^ÇÕÅACocoa Ç‹ÇΩÇÕ Carbon ÇÃÇ«ÇøÇÁÇ©ÇÁÇ≈LJíPèÉÇ»éËë±Ç´Ç≈éÊìæÇµÇ‹Ç∑ÅBCocoa Mach-O Ç‹ÇΩÇÕ Carbon Mach-O Ç≈ÇÕÅAä˘ë∂Çà NSLookupAndBindSymbol Çégópǵǃ OpenGL ÉGÉìÉgÉäÉ|ÉCÉìÉgÇÃÉAÉhÉåÉXÇéÊìæÇµÇ‹Ç∑ÅBCarbon CFM Ç≈ÇÕéËë±Ç´Ç™Ç‚Ç‚ï°éGÇ≈ÅAOpenGL Framework ÉoÉìÉhÉãÇíTǵèoǵÅACFBundleGetFunctionPointerForName ä÷êîÇégópǵǃé¿ç€ÇÃä÷êîÇéÊìæÇ∑ÇÈïKóvǙdžÇËÇ‹Ç∑ÅBCarbon ÇÃéËë±Ç´ÇÕÅAǪÇÃNjNj Mach-O Ç®ÇÊÇ— CFM Çà 2 ǬÇÃÉoÉCÉiÉäå`éÆÇ≈LJã@î\ǵNjÇ∑ÅB

OpenGL ÇÃÉGÉìÉgÉäÉ|ÉCÉìÉgÇÃêîÇÕëùǶë±ÇØÇƒÇ¢Ç‹Ç∑Ç™ÅAëSÉGÉìÉgÉäÉ|ÉCÉìÉgǙdžÇÁljÇÈÉoÅ[ÉWÉáÉìÇà Mac OS X Ç≈ÉGÉNÉXÉ|Å[ÉgÇ≥ÇÍǃǢÇÈÇÌÇØÇ≈ÇÕdžÇËÇ‹ÇπÇÒÅBä÷êîÉ|ÉCÉìÉ^ÇégópÇ∑ÇÈÇΔǢǧDZÇÃéËñ@ÇÅAìKêÿÇ»ägí£ÉXÉgÉäÉìÉOÇÃÉ`ÉFÉbÉNÇ®ÇÊÇ— OpenGL ÇÃÉoÅ[ÉWÉáÉìÉ`ÉFÉbÉNÇΔëgÇ›çáÇÌÇπÇÍÇŒÅAäJî≠é“ÇÕÅAMac OS X ÇÃëΩólÇ»ÉoÅ[ÉWÉáÉìÇëŒè€Ç…äJî≠ÇçsǧDZÇΔÇ™Ç≈Ç´Ç‹Ç∑ÅBDZÇÍÇÕÅAÉäÉìÉNéûdžÇÈÇ¢ÇÕé¿çséûÇ…ÉGÉìÉgÉäÉ|ÉCÉìÉgÇ™ÉTÉ|Å[ÉgÇ≥ÇÍǃǢÇÈǩǫǧǩÇñ‚ǢNjÇπÇÒÅBÇ≥ÇÁÇ…ÅAWindows Ç‹ÇΩÇÕ Linux èoêgÇÃëΩÇ≠ÇÃäJî≠é“Ç™égópÇ∑ÇÈÉRÅ[ÉhÇ≈ÇÕÅAwglGetProcAddress ÇÃÇÊǧǻä÷êîÇégópǵǃ OpenGL ÉGÉìÉgÉäÉ|ÉCÉìÉgÇ÷ÇÃä÷êîÉ|ÉCÉìÉ^ÇéÊìæÇ∑ÇÈédçûǛDžǻǡǃǢNjÇ∑ÅBDZÇà QÅïA Ç≈ÇÕÅADZÇÍÇÁÇÃñ‚ëËÇ…ëŒÇ∑ÇÈâåàï˚ñ@ÇíÒãüǵÅAMac OS X Ç≈ä÷êîÉ|ÉCÉìÉ^Çä»íPÇ…égópÇ≈Ç´ÇÈÇÊǧDžǵNjÇ∑ÅBâ∫ãLÇÃÉäÉXÉgÇ…ÅAMach-O ÉAÉvÉäÉPÅ[ÉVÉáÉìÇ®ÇÊÇ— CFM ÉAÉvÉäÉPÅ[ÉVÉáÉìå¸ÇØÇà Cocoa ÉoÅ[ÉWÉáÉìÇ®ÇÊÇ— Carbon ÉoÅ[ÉWÉáÉìÇà GetProcAddress Çé¶ÇµÇ‹Ç∑ÅB

ÉäÉXÉg 1 Ç…ÅANSGLGetProcAddress ÇÃè⁄ç◊Çé¶ÇµÇ‹Ç∑ÅBDZÇÃÉRÅ[ÉhÇ≈ÇÕÇ‹Ç∏ÅAóvãÅÇ≥ÇÍÇΩÉVÉìÉ{ÉãÉlÅ[ÉÄÇïWèÄìIÇ»ñºëOÉ}ÉìÉOÉäÉìÉOÅiñºëOïœä∑ÅjãKë•Ç…è]ǡǃèCê≥ǵÇΩå„ÅAÉVÉìÉ{ÉãÇ™íËã`Ç≥ÇÍǃǢÇÈDZÇΔÇämîFǵǃǢNjÇ∑ÅBǪǵǃç≈å„Ç…ÅAÉVÉìÉ{ÉãÇí≤Ç◊ǃìKêÿÇ»É|ÉCÉìÉ^Çï‘ǵǃǢNjÇ∑ÅBDZÇÃÇÊǧDžǵǃï‘Ç≥ÇÍÇΩÉ|ÉCÉìÉ^ÇégópÇ∑ÇÈëOÇ…ÇÕÅAÉ|ÉCÉìÉ^Ç™óLå¯Ç»ÅiÉ[ÉçÇ≈ÇÕǻǢÅjDZÇΔÇämîFÇ∑ÇÈÇ◊Ç´Ç≈Ç∑ÅBǻǮÅANSSymbol ä÷êîÇÕ system framework ÇÃàÍïîÇ≈džǡǃÅACocoa ÇÃàÍïîÇ≈ÇÕǻǢÇÃÇ≈ÅANSGLGetProcAddress ÇÕ Cocoa ÉAÉvÉäÉPÅ[ÉVÉáÉìÇ…ÇÕÇ‡ÇøÇÎÇÒÇÃDZÇΔÅAMach-O Carbon ÉAÉvÉäÉPÅ[ÉVÉáÉìDžLJégópÇ≈Ç´Ç‹Ç∑ÅB



 #import <mach-o/dyld.h>
 #import <stdlib.h>
 #import <string.h>
void *NSGLGetProcAddress(const char *name)
{
    NSSymbol symbol;
    char *symbolName;
    // UNIX Ç…Ç®ÇØÇÈ C ÇÃÉVÉìÉ{ÉãÉ}ÉìÉOÉäÉìÉOãKë•
    // Ç…è]ǡǃÅAÅe_ÅfÇëOÇ…ïtÇØÇ‹Ç∑
    symbolName = malloc (strlen (name) + 2);
    strcpy(symbolName + 1, name);
    symbolName[0] = '_';
    symbol = NULL;
    if (NSIsSymbolNameDefined (symbolName))
        symbol = NSLookupAndBindSymbol (symbolName);
    free (symbolName);
    return symbol ? NSAddressOfSymbol (symbol) : NULL;
}

ÉäÉXÉg 1. NSGLGetProcAddress



ÉäÉXÉg 2 Ç…é¶Ç∑ aglGetProcAddress Ç…ÇÕ 3 ǬÇÃä÷êîÇ™ä‹Ç‹ÇÍǃǢNjÇ∑ÅB1 Ǭñ⁄ÇÕ aglInitEntryPoints Ç≈Ç∑ÅBDZÇÍÇÕÅAÉoÉìÉhÉãéQèΔÇÉZÉbÉgÉAÉbÉvǵNjÇ∑ÅB2 Ǭñ⁄ÇÕ aglDellocEntryPoints Ç≈Ç∑ÅBDZÇÍÇÕéQèΔÇÃâï˙Ç…ÇÊÇËÉoÉìÉhÉãÇàÍë|ǵNjÇ∑ÅBǪǵǃ 3 Ǭñ⁄ÇÕÅAé¿ç€Ç…ÉAÉhÉåÉXÇéÊìæÇ∑ÇÈ aglGetProcAddress ä÷êîÇ≈Ç∑ÅBaglInitEntryPoints Çå©ÇÈÇΔÅAèâä˙ÉZÉbÉgÉAÉbÉvÇÃå„Ç…ÅAÅuFrameworksÅvÉtÉHÉãÉ_ÇíTǵèoǵǃ CFURL Ç÷ïœä∑Ç∑ÇÈÇΩÇflÇÃèàóùÇ™ë±Ç´ÅAç≈å„Ç…ÉoÉìÉhÉãÇçÏê¨ÇµÇƒé¿çsÉtÉ@ÉCÉãÇÉçÅ[ÉhǵǃǢÇÈDZÇΔÇ™ÇÌÇ©ÇËÇ‹Ç∑ÅBǢǡÇΩÇÒDZÇÃèàóùÇ™äÆóπÇ∑ÇÍÇŒÅAOpenGL Framework ÇÃä˘ë∂ÇÃîCà”ÇÃÉGÉìÉgÉäÇëŒè€Ç… aglGetProcAddress ÇåƒÇ—èoÇπÇ‹Ç∑ÅBèIóπéûÅAÉAÉvÉäÉPÅ[ÉVÉáÉìÇÕïKÇ∏ aglDellocEntryPoints ÇåƒÇ—èoǵǃÉoÉìÉhÉãÇÃäÑÇËìñǃÇâèúÇ∑ÇÈïKóvǙdžÇËÇ‹Ç∑ÅBaglDellocEntryPoints ÇÕÅAÉoÉìÉhÉãÇÉAÉìÉçÅ[ÉhǵÅAǪÇÍÇ…ëŒÇ∑ÇÈÉäÉtÉ@ÉåÉìÉXÇâï˙Ç∑ÇÈLJÇÃÇ≈Ç∑ÅBDZÇÃÉRÅ[ÉhÇÕ Carbon ÇëOíÒÇΔǵǃǮÇËÅAMach-O Carbon ÉAÉvÉäÉPÅ[ÉVÉáÉìÇ®ÇÊÇ— CFM Carbon ÉAÉvÉäÉPÅ[ÉVÉáÉìÇ≈ìÆçÏÇ∑ÇÈÇÊǧDžê›åvÇ≥ÇÍǃǢNjÇ∑ÅB



 #include <Carbon/Carbon.h>
CFBundleRef gBundleRefOpenGL = NULL;

// -------------------------

OSStatus aglInitEntryPoints (void)
{
    OSStatus err = noErr;
    const Str255 frameworkName = "\pOpenGL.framework";
    FSRefParam fileRefParam;
    FSRef fileRef;
    CFURLRef bundleURLOpenGL;

    memset(&fileRefParam, 0, sizeof(fileRefParam));
    memset(&fileRef, 0, sizeof(fileRef));

    fileRefParam.ioNamePtr  = frameworkName;
    fileRefParam.newRef = &fileRef;

    // ÅuFrameworksÅvÉfÉBÉåÉNÉgÉäÅ^ÉtÉHÉãÉ_
    err = FindFolder (kSystemDomain, kFrameworksFolderType, false,
                      &fileRefParam.ioVRefNum, &fileRefParam.ioDirID);
    if (noErr != err) {
        DebugStr ("\pCould not find frameworks folder");
        return err;
    }
    err = PBMakeFSRefSync (&fileRefParam); // ÉtÉHÉãÉ_ÇéwÇ∑ FSRef ÇçÏê¨Ç∑ÇÈ
    if (noErr != err) {
        DebugStr ("\pCould make FSref to frameworks folder");
        return err;
    }
    // ÉtÉHÉãÉ_ÇéwÇ∑ URL ÇçÏê¨Ç∑ÇÈ
    bundleURLOpenGL = CFURLCreateFromFSRef (kCFAllocatorDefault,
                                            &fileRef);
    if (!bundleURLOpenGL) {
        DebugStr ("\pCould create OpenGL Framework bundle URL");
        return paramErr;
    }
    // GL ÇÃÉoÉìÉhÉãÇéwÇ∑ Ref ÇçÏê¨Ç∑ÇÈ
    gBundleRefOpenGL = CFBundleCreate (kCFAllocatorDefault,
                                       bundleURLOpenGL);
    if (!gBundleRefOpenGL) {
        DebugStr ("\pCould not create OpenGL Framework bundle");
        return paramErr;
    }
    CFRelease (bundleURLOpenGL); // çÏê¨ÇµÇΩÉoÉìÉhÉãÇâï˙Ç∑ÇÈ
    // ÉoÉìÉhÉãÇÃÉRÅ[ÉhÇê≥ǵÇ≠ÉçÅ[ÉhÇ≈Ç´ÇΩÇÁÅAÉtÉ@ÉìÉNÉVÉáÉìÇíTÇ∑
    if (!CFBundleLoadExecutable (gBundleRefOpenGL)) {
        DebugStr ("\pCould not load MachO executable");
        return paramErr;
    }
    return err;
}

// -------------------------

void aglDellocEntryPoints (void)
{
    if (gBundleRefOpenGL != NULL) {
        // ÉoÉìÉhÉãÇÃÉRÅ[ÉhÇÉAÉìÉçÅ[ÉhǵNjÇ∑
        CFBundleUnloadExecutable (gBundleRefOpenGL);
        CFRelease (gBundleRefOpenGL);
        gBundleRefOpenGL = NULL;
    }
}

// -------------------------

void * aglGetProcAddress (char * pszProc)
{
    return CFBundleGetFunctionPointerForName (gBundleRefOpenGL,
                CFStringCreateWithCStringNoCopy (NULL,
                     pszProc, CFStringGetSystemEncoding (), NULL));
}

ÉäÉXÉg 2. aglGetProcAddress



ÉäÉXÉg 3 ÇΔÉäÉXÉg 4 Ç…ÉRÅ[ÉhÇÃî≤êàÇ 2 Ǭé¶ÇµÇ‹Ç∑ÅBDZÇÍÇÁÇÕÅAÇ¢Ç≠ǬǩÇà OpenGL ÉGÉìÉgÉäÉ|ÉCÉìÉgÇëŒè€Ç… aglGetProcAddress ÇΔ NSGLGetProcAddress ÇégópÇ∑ÇÈï˚ñ@Çé¶ÇµÇ‹Ç∑ÅBóºé“ÇÕëÂïœÇÊÇ≠éóǃǢNjÇ∑Ç™ÅAaglGetProcAddress Ç≈ÇÕ aglInitEntryPoints ÇåƒÇ—èoǵǃÅAä÷êîÉ|ÉCÉìÉ^ÇÃéÊìæÇ…êÊóßǡǃÉoÉìÉhÉãÇÉçÅ[ÉhǵÅAaglDellocEntryPoints ÇåƒÇ—èoǵǃÅAÉAÉvÉäÉPÅ[ÉVÉáÉìÇÃèIóπÇ…êÊóßǡǃÉoÉìÉhÉãÇÉAÉìÉçÅ[ÉhǵǃǢNjÇ∑ÅBDZÇÍÇÁà»äOÇÃì_Ç≈ÇÕÅAóºé“ÇÕÇŸÇ⁄ìØÇ∂Ç≈Ç∑ÅB



#import "NSGLGetProcAddress.h" // ÉäÉXÉg 1 Ç…Ç®ÇØÇÈ aglGetProcAddress ÉtÉ@Éì
                               // ÉNÉVÉáÉìÇéÊìæÇ∑ÇÈÉwÉbÉ_ÉtÉ@ÉCÉã

static void InitEntryPoints (void);
static void DeallocEntryPoints (void);

// ÉtÉ@ÉìÉNÉVÉáÉìÉ|ÉCÉìÉ^Ç typedef Ç≈íËã`Ç∑ÇÈ
    typedef void (*glBlendColorProcPtr)(GLclampf red,
                                        GLclampf green,
                                        GLclampf blue,
                                        GLclampf alpha);
    typedef void (*glBlendEquationProcPtr)(GLenum mode);
    typedef void (*glDrawRangeElementsProcPtr)(GLenum mode,
                                               GLuint start,
                                               GLuint end,
                                               GLsizei count,
                                               GLenum type,
                                               const GLvoid *indices);

// ÉtÉ@ÉìÉNÉVÉáÉìÉ|ÉCÉìÉ^êÈåæ
// íçà”ÅFÉtÉ@ÉìÉNÉVÉáÉìñºÇǪÇÃNjNjégópǵǻǢDZÇΔ
// pfXXX ÇÕÅAÅuÉtÉ@ÉìÉNÉVÉáÉìÇ÷ÇÃÉ|ÉCÉìÉ^ÅvÇ
// Çï\Ç∑è»ó™å`ÇΔǵǃëIÇÒÇæ
    glBlendColorProcPtr pfglBlendColor = NULL;
    glBlendEquationProcPtr pfglBlendEquation = NULL;
    glDrawRangeElementsProcPtr pfglDrawRangeElements  = NULL;

// ==========================

static void InitEntryPoints (void)
{
    pfglBlendColor = (glBlendColorProcPtr)
                         NSGLGetProcAddress ("glBlendColor");
    pfglBlendEquation = (glBlendEquationProcPtr)
                            NSGLGetProcAddress ("glBlendEquation");
    pfglDrawRangeElements = (glDrawRangeElementsProcPtr)
                                NSGLGetProcAddress ("glDrawRangeElements");
}

// -------------------------

static void DeallocEntryPoints (void)
{
    pfglBlendColor = NULL;
    pfglBlendEquation = NULL;
    pfglDrawRangeElements = NULL;;
}

ÉäÉXÉg 3. NSGLGetProcAddress ÇÃégópó·





#include "aglGetProcAddress.h" // ÉäÉXÉg 2 Ç…Ç®ÇØÇÈ aglGetProcAddress Ét
                               // É@ÉìÉNÉVÉáÉìÇéÊìæÇ∑ÇÈÉwÉbÉ_ÉtÉ@ÉCÉã

static OSStatus InitEntryPoints (void);
static void DeallocEntryPoints (void);

// ÉtÉ@ÉìÉNÉVÉáÉìÉ|ÉCÉìÉ^Ç typedef Ç≈íËã`Ç∑ÇÈ
    typedef void (*glBlendColorProcPtr)(GLclampf red,
                                        GLclampf green,
                                        GLclampf blue,
                                        GLclampf alpha);
    typedef void (*glBlendEquationProcPtr)(GLenum mode);
    typedef void (*glDrawRangeElementsProcPtr)(GLenum mode,
                                               GLuint start,
                                               GLuint end,
                                               GLsizei count,
                                               GLenum type,
                                               const GLvoid *indices);

// ÉtÉ@ÉìÉNÉVÉáÉìÉ|ÉCÉìÉ^êÈåæ
// íçà”ÅFÉtÉ@ÉìÉNÉVÉáÉìñºÇǪÇÃNjNjégópǵǻǢDZÇΔ
// pfXXX ÇÕÅAÅuÉtÉ@ÉìÉNÉVÉáÉìÇ÷ÇÃÉ|ÉCÉìÉ^ÅvÇ
// ï\Ç∑è»ó™å`ÇΔǵǃëIÇÒÇæ
    glBlendColorProcPtr pfglBlendColor = NULL;
    glBlendEquationProcPtr pfglBlendEquation = NULL;
    glDrawRangeElementsProcPtr pfglDrawRangeElements  = NULL;

// ==========================

static OSStatus InitEntryPoints (void)
{
    OSStatus err = aglInitEntryPoints (); // ÉoÉìÉhÉãÇÃèâä˙âª
    if (noErr == err) {
        pfglBlendColor = (glBlendColorProcPtr)
                            aglGetProcAddress ("glBlendColor");
        pfglBlendEquation = (glBlendEquationProcPtr)
                                aglGetProcAddress ("glBlendEquation");
        pfglDrawRangeElements = (glDrawRangeElementsProcPtr)
                                    aglGetProcAddress ("glDrawRangeElements");
    }
    return err;
}

// -------------------------

static void DeallocEntryPoints (void)
{
    pfglBlendColor = NULL;
    pfglBlendEquation = NULL;
    pfglDrawRangeElements = NULL;;
    aglDellocEntryPoints (); // ÉoÉìÉhÉãÇÃîjä¸
}

ÉäÉXÉg 4. aglGetProcAddress ÇÃégópó·



OpenGL ÉGÉìÉgÉäÉ|ÉCÉìÉgÇ÷ÇÃä÷êîÉ|ÉCÉìÉ^ÇÃégópÇ…ä÷ǵǃÅALJǧàÍì_ÅAímǡǃǮÇ≠ÇΔÇÊǢDZÇΔǙdžÇËÇ‹Ç∑ÅBóLå¯Ç»ä÷êîÉ|ÉCÉìÉ^ÇéÊìæÇ≈ǴǃLJÅAǪÇÍÇÕǪÇÃÉGÉìÉgÉäÉ|ÉCÉìÉgÇ™ OpenGL Framework Ç…ÇÊǡǃÉGÉNÉXÉ|Å[ÉgÇ≥ÇÍǃǢÇÈDZÇΔÇà”ñ°Ç∑ÇÈÇæÇØÇ≈ÅAǪÇÃÉãÅ[É`ÉìÇ™ÉTÉ|Å[ÉgÇ≥ÇÍǃǢǃÅAÉAÉvÉäÉPÅ[ÉVÉáÉìÇÃíÜÇ©ÇÁåƒÇ—èoÇπÇÈǩǫǧǩÇé¶Ç∑LJÇÃÇ≈ÇÕdžÇËÇ‹ÇπÇÒÅBOpenGL ÉAÉvÉäÉPÅ[ÉVÉáÉìÇ≈ÇÕÅAÅiìÆìIÇ…ÉçÅ[ÉhÇ≥ÇÍÇΩǩǫǧǩDžǩǩÇÌÇÁÇ∏ÅjOpenGL ÉGÉìÉgÉäÉ|ÉCÉìÉgÇåƒÇ—èoÇ∑ëOÇ…ÅAïKÇ∏ÉåÉìÉ_ÉâÇÃåªç›ÇÃägí£ÉXÉgÉäÉìÉOÇ‹ÇΩÇÕ OpenGL ÇÃÉoÅ[ÉWÉáÉìî‘çÜÅAdžÇÈÇ¢ÇÕǪÇÃóºï˚ÇÉ`ÉFÉbÉNǵǃÅAégǮǧÇΔǵǃǢÇÈã@î\Ç™ÉTÉ|Å[ÉgÇ≥ÇÍǃǢÇÈǩǫǧǩÇämîFÇ∑ÇÈÇ◊Ç´Ç≈Ç∑ÅBǬNjÇËÅAÉäÉìÉNéûÇ‹ÇΩÇÕé¿çséûÇÃÉGÉìÉgÉäÉ|ÉCÉìÉgÇÃë∂ç›ÇÕÅAì¡íËÇÃÉåÉìÉ_ÉâDžǮǢǃì¡íËÇÃã@î\Ç™ÉTÉ|Å[ÉgÇ≥ÇÍǃǢÇÈDZÇΔÇé¶Ç∑LJÇÃÇ≈ÇÕdžÇËÇ‹ÇπÇÒÅB

Ç‹ÇΔÇflÇÈÇΔÅAï°êîÉoÅ[ÉWÉáÉìÇà OS ÇëŒè€Ç…äJî≠ÇÇ∑ÇÈèÍçáÅAëŒè€ÇΔÇ»ÇÈÇ∑Ç◊ǃÇà OS ÉoÅ[ÉWÉáÉìÇ…ÉGÉìÉgÉäÉ|ÉCÉìÉgÇ™ë∂ç›Ç∑ÇÈÇΔÇÕå¿ÇÁǻǢÇΩÇflÅAñ¢íËã`ÇÃÉGÉìÉgÉäÉ|ÉCÉìÉgÇ…ÇÊÇÈãNìÆÉGÉâÅ[ÇâÒîÇ∑ÇÈÇΩÇflÇ…ÅACFM ÉAÉvÉäÉPÅ[ÉVÉáÉìÇ≈ÇÕÅAOpenGL ÉXÉ^ÉuÉâÉCÉuÉâÉäÇ…ëŒÇ∑ÇÈé„Ç¢ÉäÉìÉNÇóLÇ∑ÇÈÇ©ÅAä÷êîÉ|ÉCÉìÉ^ÇégópÇ∑ÇÈDZÇΔÇ™ñ]NjǵÇ≠ÅAMach-O ÉAÉvÉäÉPÅ[ÉVÉáÉìÇ≈ÇÕÅAÉGÉìÉgÉäÉ|ÉCÉìÉgÇ÷ÇÃä÷êîÉ|ÉCÉìÉ^ÇégópÇ∑ÇÈDZÇΔÇ™ñ]NjǵǢÇΔǢǧDZÇΔÇ…Ç»ÇËÇ‹Ç∑ÅB


[2002 îN 11 åé 25 ì˙]